import * as fs from "fs";
import * as util from "util";

import { _del } from "./del";
import * as _mkdirp from "mkdirp";

const xlsx = require("node-xlsx");
const _copy = require("copy");
const _rmdir = require("rmdir");
const path = require("path");

import * as log from "./log";

export const replaceAll = (find: string, replace: string, str: string) => {
	var find = find.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
	return str.replace(new RegExp(find, "g"), replace);
};

export const readDataFromFile = util.promisify(fs.readFile);

export const readTextFromFile = (path: string): Promise<string> => {
	return new Promise((resolve, reject) => {
		fs.readFile(path, "utf8", (err, data) => {
			if (err) {
				reject(err);
			} else {
				resolve(data);
			}
		});
	});
};

export const writeFile = (path: string, data: any): Promise<void> => {
	return new Promise((resolve, reject) => {
		fs.writeFile(path, data, err => {
			if (err) {
				reject(err);
			} else {
				resolve();
			}
		});
	});
};

export const readDir = (path: fs.PathLike): Promise<string[]> => {
	return new Promise((resolve, reject) => {
		fs.readdir(path, (err, files) => {
			if (err) {
				reject(err);
			} else {
				resolve(files);
			}
		});
	});
};

export const getFsStat = (path: fs.PathLike): Promise<fs.Stats> => {
	return new Promise((resolve, reject) => {
		fs.stat(path, (err, stats) => {
			if (err) {
				reject(err);
			} else {
				resolve(stats);
			}
		});
	});
};

export const isFile = async (path: fs.PathLike) => {
	try {
		return (await getFsStat(path)).isFile();
	} catch (err) {
		return false;
	}
};

export const isDirectory = async (path: fs.PathLike) => {
	try {
		return (await getFsStat(path)).isDirectory();
	} catch (err) {
		return false;
	}
};

export const rename = (oldPath: fs.PathLike, newPath: fs.PathLike): Promise<void> => {
	return new Promise((resolve, reject) => {
		fs.rename(oldPath, newPath, err => {
			if (err) {
				reject(err);
			} else {
				resolve();
			}
		});
	});
};

export const unlink = util.promisify(fs.unlink);

export const mkdirp = (dir: string): Promise<string> => {
	return new Promise((resolve, reject) => {
		_mkdirp(dir, (err, made) => {
			if (err) {
				reject(err);
			} else {
				resolve(made);
			}
		});
	});
};

export const rmdir = (path: string): Promise<string[]> => {
	return new Promise((resolve, reject) => {
		_rmdir(path, (err: any, dirs: string[], files: string[]) => {
			if (err) {
				reject(err);
			} else {
				resolve(dirs.concat(files));
			}
		});
	});
};

export const copy = (src: string, dst: string): Promise<string[]> => {
	return new Promise((resolve, reject) => {
		_copy(src, dst, (err: any, files: string[]) => {
			if (err) {
				reject(err);
			} else {
				resolve(files);
			}
		});
	});
};

export const del = (_path: string | string[]): Promise<string[]> => {
	return _del(_path, { force: true });
};

//递归创建目录 同步方法
export const mkdirsSync = (dirname: string) => {
	if (fs.existsSync(dirname)) {
		return true;
	} else {
		if (mkdirsSync(path.dirname(dirname))) {
			console.log("mkdirsSync = " + dirname);
			fs.mkdirSync(dirname);
			return true;
		}
	}
};

export const copyDirFiles = (src: string, dist: string) => {
	var paths = fs.readdirSync(src);
	paths.forEach(function(p) {
		var _src = src + "/" + p;
		var _dist = dist + "/" + p;
		var stat = fs.statSync(_src);
		if (stat.isFile()) {
			// 判断是文件还是目录
			fs.writeFileSync(_dist, fs.readFileSync(_src));
		} else if (stat.isDirectory()) {
			copyDir(_src, _dist); // 当是目录是，递归复制
		}
	});
};

/*
 * 复制目录、子目录，及其中的文件
 * @param src {String} 要复制的目录
 * @param dist {String} 复制到目标目录
 */
export const copyDir = (src: string, dist: string) => {
	var b = fs.existsSync(dist);
	console.log("dist = " + dist);
	if (!b) {
		console.log("mk dist = ", dist);
		mkdirsSync(dist); //创建目录
	}
	console.log("_copy start");
	_copy(src, dist);
};

// 导出excel
export const writeXls = (datas: any, exlName: string) => {
	var buffer = xlsx.build([{ name: "Groups", data: datas }]);
	fs.writeFileSync(exlName + ".csv", buffer, "binary");
};

// 查找子串出现的次数
export const findSunStrCount = (source: string, target: string) => {
	let count = 0;
	//每次查询开始的位置
	let fromIndex = 0;
	while ((fromIndex = source.indexOf(target, fromIndex)) != -1) {
		count++;
		fromIndex = fromIndex + target.length;
	}
	return count;
};
